{***************************************************************
    SpyGestion  Copyright (C) 2008 Christophe KOALI <nature2gas@gmail.com>
    
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.
    
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
    
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
    
****************************************************************}
unit modListeAttaqueCollection;

interface

(***************************************

 Contient une liste de cible que le robot attaque lorsqu'un slot se libère


******************************************)

uses modFlotteVaisseauxChoix, modBaseDeDonnesRapport,
     modBaseType,
     modClasses,
     modPlanete,
     sFonctionsChaines,
     modRapport,
     Controls, ExtCtrls,
     Math,

     modListeAttaqueVaisseauxInfos,

     Classes, SysUtils;




type
    // permet de déterminer le type du pointeur dans le record
    TLAActionType = (laatAttaquer, laatTransporter);

    TLActionSondageStatus = (lassIdle, lassAttenteRapport);


    
    TLAActionSondageInfos = record
        // planète à utiliser pour sonder avant de lancer le raid (ou avant l'impact)
        // elle peut être différente de la planète de départ
        Planete: TPlanetLocation;


        // Durée en seconde que met la sonde pour atteindre la cible
        // On ne connait pas la cible ici, mais cette durée est déterminé
        // avec d'autres informations
        DureePourAtteindreLaCible: integer;

        
        // Sondage avant impact
        // et annule si la valeur de score defense OU recyclage max ressource
        // sont supérieures à celles connues
        DoAvantImpact: integer;

        // sondage avant d'envoyer l'attaque
        DoAvantAttaque: integer;

        // sondage status
        Status: TLActionSondageStatus;

        // nombre de sondes à envoyer pour connaitre la défense et la flotte
        NbSondes   : integer;

        // date d'impact de la sonde pour pouvoir lire le rapport d'espionnage
        // ce champ est utilisé avant d'envoyer la flotte, ET avant l'impact
        FlotteImpactDate: int64;

        // date de lancement de ou des sondes pour permettre de savoir si cela
        // fait trop longtemps que l'on attend le rapport d'espionnage
        FlotteLaunchDate: int64;


        // on va vérifier la liste des messages pour savoir si le rapport est arrivée
        // pour éviter de le faire chaque seconde, on utilise un intervalle, pour cela
        // on a besoin de connaitre la date de la dernière consultation
        // Update: on utilise à présent la date de prochaine vérification
        NextRapportChecking: int64;
    end;



    // le robot peut recalculer le nombre de GT à envoyer
    // à partir du rapport d'espionnage
    TLAActionVaisseauxRessourceAjustement = record
        // défini si le calcul est activé
        AutoAjustActive: boolean;

        // si la partie décimale du nombre de GT est supérieur à cette valeur
        // alors le nombre de GT sera incrémenté de 1
        FractionMajoration: single;

        // une fois le nomre de GT obtenu, on peut choisir d'ajouter
        // 1 ou plusieurs GT (pour prendre en compte la production durant le voyage)
        // ce nombre est défini par l'humain
        AjoutSupplementaire: integer;

        // Version avec PT
        // Exactement la même chose mais on modifie le nombre de PT
        PTVersion: boolean;
    end;

    TLAActionOrdreAttaquer = record
        // minimum de ressource pour envoyer le raid
        RessourceMin     : integer;

        // maximum de défense pour envoyer le raid
        DefenseScoreMax  : integer;

        // maximum de vaisseaux à quai pour envoyer le raid
        RecyclageNbRessourceMax   : integer;

        // informations de sondages
        Sondage: TLAActionSondageInfos;

        
        ///////////////////////////////////////////
        // si le sondage est effecté avant l'attaque et que le rapport est lu
        // le robot peut recalculer le nombre de GT à envoyer
        VaisseauxAjustement: TLAActionVaisseauxRessourceAjustement;
    end;
    PLAActionOrdreAttaquer = ^TLAActionOrdreAttaquer;


    TLAActionOrdreTransporter = record
       // la planète cible est déjà connue par le record TLAItem
       MetalOrder     : integer;
       CristalOrder   : integer;
       DeuteriumOrder : integer;


       // minimum de ressource total pour exécuter l'action
       MinTotalRessource: integer;
    end;
    PLAActionOrdreTransporter = ^TLAActionOrdreTransporter;



    TLAItem = record
       // planète d'où on doit lancer la flotte
       Depart    : TPlanetLocation;

       // défini la cible, l'ordre
       Operation : TFlotteEnvoiData;

       // défini les vaisseaux à utiliser
       Vaisseaux : TLAVaisseauxInfos;

       ActionOrdreType: TLAActionType;
       ActionOrdre    : pointer;

       // si jamais il manque des vaisseaux, ou si il y a plus de slot de libre
       // alors il faut fixer une date d'attente pour éviter de trop télécharger
       // les pages web
       DateCanPrisEnCompte: int64;

       // date à laquelle l'action a été prise en compte PUIS effectué
       DateEffecue: int64;

       // on peut définir une date avant laquelle l'élément ne doit pas être lancé
       // mais cela ne signifie pas qu'il sera lancé à cette date, mais dès qu'un slot sera libre à partir de cette date
       NePasExecuterAvant: int64;
    end;
    PLAItem = ^TLAItem;



    // le pointeur est construit à l'extérieur, mais est détruit par la classe
    TCollectionListeAction = class(TList)
    private

    public


        function GetNextItemToDo: PLAItem;

        // Efface la liste et libère les pointeurs
        procedure FreePointeurAndClear;

    end;




implementation

procedure TCollectionListeAction.FreePointeurAndClear;
var i: integer;
    pe: PLAItem;
begin

    if Count = 0 then begin
       exit;
    end;

    for i := Count - 1 downto 0 do begin
       pe := Items[i];

       if pe.ActionOrdre <> nil then begin
          Dispose(pe.ActionOrdre);
          pe.ActionOrdre := nil;
       end;

       Dispose(pe);
       Delete(i);
    end;

    Clear;
end;

function TCollectionListeAction.GetNextItemToDo: PLAItem;
var i: integer;
    pe: PLAItem;
begin

    Result := nil;

    for i := 0 to Count - 1 do begin
       pe := Items[i];

       if pe.DateEffecue > 100 then begin
          // déjà effectué
          Continue;
       end;

       Result := pe;
       exit;
    end;

end;

end.
